package com.msgc.utils.crypto.negotiation.util;

import com.msgc.utils.crypto.aes.exception.AesCryptoException;
import com.msgc.utils.crypto.aes.exception.SymmetricCryptoException;
import com.msgc.utils.crypto.asymmetric.exception.AsymmetricCryptoException;
import com.msgc.utils.crypto.asymmetric.exception.KeyPairException;
import com.msgc.utils.crypto.common.ByteSpecification;
import com.msgc.utils.crypto.negotiation.cache.dto.KeyExchangeResult;
import com.msgc.utils.crypto.negotiation.dto.KeyExchangeRequest;
import com.msgc.utils.crypto.negotiation.dto.KeyExchangeResponse;
import com.msgc.utils.crypto.negotiation.exception.NegotiationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 为 String 提供适配
 * @author Admin
 */
@Component
public class TransportCryptoUtilAdapter implements ByteSpecification {

    @Autowired
    private TransportCryptoUtil adaptee;

    /**
     * 创建一个请求
     */
    public KeyExchangeRequest createRequest() throws AsymmetricCryptoException {
        return adaptee.createRequest();
    }

    /**
     * 创建一个响应
     */
    public KeyExchangeResponse createResponse(KeyExchangeRequest keyExchangeRequest) throws Exception {
        return adaptee.createResponse(keyExchangeRequest);
    }

    /**
     *  协商密钥与 iv
     */
    public KeyExchangeResult negotiation(KeyExchangeResponse keyExchangeResponse) throws KeyPairException, NegotiationException {
        return adaptee.negotiation(keyExchangeResponse);
    }
    public KeyExchangeResponse negotiation(KeyExchangeRequest keyExchangeRequest) throws NegotiationException, AsymmetricCryptoException {
        return adaptee.negotiation(keyExchangeRequest);
    }

    /**
     * 生成数据密钥
     */
    public static byte[] generateDataKey(int size) {
        return TransportCryptoUtil.generateDataKey(size);
    }

    /**
     * 生成数据密钥的密文（用于协商完毕，每次请求中）
     * @return xDk
     */
    public static String encryptDk(KeyExchangeResult keyExchangeResult, byte[] dataKey) throws AesCryptoException {
        return ByteSpecification.encodeToString(TransportCryptoUtil.encryptDk(keyExchangeResult, dataKey));
    }

    /**
     * 解密 xDk（用于协商完毕，每次请求中）
     * @return dataKey
     */
    public static byte[] decryptDk(KeyExchangeResult keyExchangeResult, String xDk) throws SymmetricCryptoException {
        return TransportCryptoUtil.decryptDk(keyExchangeResult, ByteSpecification.decodeToBytes(xDk));
    }

    /**
     * 加密数据
     */
    public static String encrypt(KeyExchangeResult keyExchangeResult, byte[] dataKey, String toCipher) throws AesCryptoException {
        return ByteSpecification.encodeToString(TransportCryptoUtil.encrypt(keyExchangeResult, dataKey, toCipher.getBytes(CHARSET_UTF_8)));
    }

    /**
     * 解密数据
     */
    public static String decrypt(KeyExchangeResult keyExchangeResult, byte[] dataKey, String cipherText) throws AesCryptoException {
        return new String(TransportCryptoUtil.decrypt(keyExchangeResult, dataKey, ByteSpecification.decodeToBytes(cipherText)), CHARSET_UTF_8);
    }


    // =========================== TOKEN ==================================

    /**
     * 生成 token（发起协商请求时）
     */
    public String generateRequestToken(KeyExchangeRequest request) throws AsymmetricCryptoException {
        return ByteSpecification.encodeToString(adaptee.generateRequestToken(request));
    }

    /**
     * 验证 token（处理协商请求前）
     */
    public boolean verifyRequestToken(KeyExchangeRequest request) throws AsymmetricCryptoException {
        return adaptee.verifyRequestToken(request);
    }

    // -------------------------------

    /**
     * 生成 token（发起协商响应时生成）
     */
    public String generateResponseToken(KeyExchangeResponse response) throws AsymmetricCryptoException {
        return ByteSpecification.encodeToString(adaptee.generateResponseToken(response));
    }

    /**
     * 验证 token（确认协商响应请求时）
     */
    public boolean verifyResponseToken(KeyExchangeResponse response) throws AsymmetricCryptoException {
        return adaptee.verifyResponseToken(response);
    }

    // -------------------------------

    /**
     * 生成 token（协商完毕，每次发送安全会话请求时）
     * @param xDk 每次请求发过来的临时密钥
     */
    public String generateToken(String xSessionId, String xDk) throws AsymmetricCryptoException {
        return ByteSpecification.encodeToString(adaptee.generateToken(xSessionId, ByteSpecification.decodeToBytes(xDk)));
    }

    /**
     * 验证 token（协商完毕，每次处理请求时）
     */
    public boolean verifyToken(String xSessionId, String xDk, String token) throws AsymmetricCryptoException {
        return adaptee.verifyToken(xSessionId, ByteSpecification.decodeToBytes(xDk), ByteSpecification.decodeToBytes(token));
    }

    /**
     * 生成客户端的加密传输请求头（不带 xDk ）
     */
    /*public HttpHeaders generateHeaders(KeyExchangeResult keyExchangeResult) throws AsymmetricCryptoException {
        HttpHeaders headers = new HttpHeaders();
        headers.add(KeyExchangeConstants.PARAM_TOKEN, ByteSpecification.encodeToString(this.generateToken(keyExchangeResult)));
        headers.add(KeyExchangeConstants.PARAM_SECURITY_SESSION_ID, keyExchangeResult.getxSessionId());
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return headers;
    }
    public HttpHeaders generateHeaders(KeyExchangeResult keyExchangeResult, byte[] dataKey) throws AsymmetricCryptoException, AesCryptoException {
        byte[] dk = this.encryptDk(dataKey, keyExchangeResult);
        HttpHeaders headers = new HttpHeaders();
        headers.add(KeyExchangeConstants.PARAM_TOKEN, ByteSpecification.encodeToString(generateToken(dataKey, keyExchangeResult)));
        headers.add(KeyExchangeConstants.PARAM_SECURITY_SESSION_ID, keyExchangeResult.getxSessionId());
        headers.add(KeyExchangeConstants.PARAM_SECURITY_DK, ByteSpecification.encodeToString(dk));
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return headers;
    }*/

}
